﻿using System.Text;
using System.Text.RegularExpressions;

namespace RFIDStation.DeviceDriver.IModules.Impls
{
    public class CommandLineModule : IModule
    {
        private readonly ILogger _logger;
        private readonly ViewModel _viewModel;

        public CommandLineModule( ILoggerFactory loggerFactory, ViewModel viewModel )
        {
            _logger = loggerFactory.CreateLogger( nameof( CommandLineModule ) );
            _viewModel = viewModel;
        }

        public async Task StartAsync( CancellationToken cancellationToken )
        {
            if ( Environment.OSVersion.Platform != PlatformID.Win32NT ) return;

            _ = Task.Factory.StartNew( ( ) =>
            {
                while ( cancellationToken.IsCancellationRequested is false )
                {
                    try
                    {
                        var line = Console.ReadLine( );
                        if ( line.IsNullOrWhiteSpace( ) ) continue;

                        var regex = Regex.Match( line, @"(?<cmd>\w*)\s*(?<args>.*)" );
                        if ( regex.Success is false ) throw new Exception( $"无效的命令行: {line}" );

                        var cmd = regex.Groups["cmd"].Value;
                        var args = new ConfigurationBuilder( ).AddCommandLine( regex.Groups["args"].Value.ToArray( ' ' ) ).Build( );

                        switch ( cmd.ToLower( ) )
                        {
                            case "show":
                                {
                                    var builder = new StringBuilder( );

                                    var str = _viewModel.WebSocketClientList.Select( ( item, index ) => $"WS客户端 [{index + 1}] {item.ConnectionInfo.ClientIpAddress}:{item.ConnectionInfo.ClientPort}, id: {item.ConnectionInfo.Id}" ).ToStringWithNewLine( );
                                    builder.AppendLine( str );
                                    builder.AppendLine( );

                                    builder.AppendLine( $"{_viewModel.RFIDHFReader.ReaderId}, {_viewModel.RFIDHFReader.ReaderState}" );

                                    //str = _viewModel.RFIDRegisterList.Select( ( item, index ) => $"已注册标签 [{index + 1}] {item.Data} → {item.RFID}" ).ToStringWithNewLine( );
                                    //builder.AppendLine( str );

                                    ConsoleWirter.Success( builder.ToString( ) );
                                    break;
                                }
                            case "help":
                                {
                                    var builder = new StringBuilder( );

                                    builder.AppendLine( "超高频读写器-询盘:\t uhf c={扫描次数}" );
                                    builder.AppendLine( "高频读写器-询盘:\t hf c={扫描次数}" );
                                    builder.AppendLine( "高频读写器-读写EAS:\t hf_eas" );
                                    builder.AppendLine( "高频读写器-读写AFI:\t hf_afi" );
                                    builder.AppendLine( "发卡器-M1卡:\t\t m1 b={块号}" );
                                    builder.AppendLine( "发卡器-身份证:\t\t icr" );
                                    builder.AppendLine( "扫描器:\t\t\t scanner" );
                                    builder.AppendLine( );

                                    ConsoleWirter.Debug( builder.ToString( ) );
                                    break;
                                }

                            case "uhf":     // uhf c=4
                                {
                                    var scanCount = args["c"].ToIntOrDefault( defaultValue: 1 );

                                    var sw = System.Diagnostics.Stopwatch.StartNew( );
                                    var tagList = _viewModel.RFIDUHFInventoryScan( scanCount, includeTID: false );
                                    sw.Stop( );

                                    var builder = new StringBuilder( );
                                    var result = tagList.Select( ( tag, index ) => $"标签 [{( index + 1 ).ToString( "D4" )}] {tag.Reader}\t{tag.EPC}\t{tag.TID}\t{tag.ScanCount}\t{tag.AntList.Select( i => $"{i.AntNo}:{i.RSSI}:{i.Count}" ).ToStringWithComma( )}" )
                                                        .ToStringWithNewLine( );
                                    builder.AppendLine( result );
                                    builder.AppendLine( $"耗时: {sw.Elapsed.TotalSeconds} s" );
                                    builder.AppendLine( );

                                    ConsoleWirter.Success( builder.ToString( ) );
                                    break;
                                }

                            case "hf":      // hf c=2
                                {
                                    var scanCount = args["c"].ToIntOrDefault( defaultValue: 1 );

                                    var sw = System.Diagnostics.Stopwatch.StartNew( );
                                    var tagList = _viewModel.RFIDHFInventoryScan( scanCount, readBlock: true, blockStartIndex: 0, blockCount: 3 );
                                    sw.Stop( );

                                    var builder = new StringBuilder( );
                                    var result = tagList.Select( ( tag, index ) => $"标签 [{( index + 1 ).ToString( "D4" )}] {tag.Reader}\t{tag.UID}\t{tag.BlockData}\t{tag.ScanCount}\t{tag.AntList.Select( i => $"{i.AntNo}:{i.Count}" ).ToStringWithComma( )}" )
                                                        .ToStringWithNewLine( );
                                    builder.AppendLine( result );
                                    builder.AppendLine( $"耗时: {sw.Elapsed.TotalSeconds} s" );
                                    builder.AppendLine( );

                                    // 读EAS、AFI
                                    tagList.ForEach( tag =>
                                    {
                                        var eas = _viewModel.RFIDHFReader.ReadEAS( tag.UID );
                                        var afi = _viewModel.RFIDHFReader.ReadAFI( tag.UID );

                                        builder.AppendLine( $"标签: {tag.UID}, EAS: {eas}, AFI: 0x{afi.ToString( "X2" )}" );
                                    } );

                                    ConsoleWirter.Success( builder.ToString( ) );
                                    break;
                                }
                            case "hf_eas":
                                {
                                    var tagList = _viewModel.RFIDHFInventoryScan( scanCount: 1, readBlock: false, blockStartIndex: 0, blockCount: 3 );
                                    if ( tagList.IsNullOrEmpty( ) ) throw new KeyNotFoundException( $"未检测到标签" );

                                    var tagInfo = tagList.First( );

                                    var enable = _viewModel.RFIDHFReader.ReadEAS( uid: tagInfo.UID );
                                    ConsoleWirter.Success( $"read eas: {enable}" );

                                    Thread.Sleep( 2000 );

                                    enable = !enable;
                                    _viewModel.RFIDHFReader.WriteEAS( uid: tagInfo.UID, enable: enable );
                                    ConsoleWirter.Success( $"write eas: {enable}" );
                                    break;
                                }
                            case "hf_afi":
                                {
                                    var tagList = _viewModel.RFIDHFInventoryScan( scanCount: 1, readBlock: false, blockStartIndex: 0, blockCount: 3 );
                                    if ( tagList.IsNullOrEmpty( ) ) throw new KeyNotFoundException( $"未检测到标签" );

                                    var tagInfo = tagList.First( );

                                    var afi = _viewModel.RFIDHFReader.ReadAFI( uid: tagInfo.UID );
                                    ConsoleWirter.Success( $"read afi: 0x{afi.ToString( "X2" )}" );

                                    Thread.Sleep( 2000 );

                                    afi = afi == 0xC2 ? (byte)0x07 : (byte)0xC2;
                                    _viewModel.RFIDHFReader.WriteAFI( uid: tagInfo.UID, afi );
                                    ConsoleWirter.Success( $"write afi: 0x{afi.ToString( "X2" )}" );
                                    break;
                                }

                            case "m1":  // m1 b=1
                                {
                                    var block = ( args["b"] ?? "0" ).ToIntOrDefault( defaultValue: 0 );

                                    var tagInfo = _viewModel.CardReader.M1Inventory( );
                                    ConsoleWirter.Success( $"标签: {tagInfo.UID}" );

                                    var blockInfo = _viewModel.CardReader.M1ReadBlock( block );
                                    ConsoleWirter.Success( $"标签: {blockInfo.UID}, 块号: {blockInfo.BlockNo}, 数据: {blockInfo.BlockData}" );
                                    break;
                                }

                            case "icr":
                                {
                                    var tagInfo = _viewModel.CardReader.ICRInventory( );
                                    ConsoleWirter.Success( JsonConvert.SerializeObject( tagInfo ) );
                                    break;
                                }

                            case "scanner":
                                {
                                    _viewModel.Scanner.Scan( );
                                    ConsoleWirter.Success( $"操作成功" );
                                    break;
                                }

                            case "test":    // test l=10
                                {
                                    var loop = ( args["l"] ?? "1" ).ToIntOrDefault( defaultValue: 1 );

                                    //_viewModel.TestRFIDUHFReader( loop );

                                    //_viewModel.AudioService.Ready( Constants.AudioFile.SCAN );

                                    //for ( int i = 0; i < 10; i++ )
                                    //{
                                    //    _viewModel.AudioService.Play( reset: true );
                                    //}

                                    //_viewModel.AudioService.DisposeAll( );
                                    break;
                                }
                            default: throw new Exception( $"无效指令: {line}" );
                        }
                    }
                    catch ( Exception ex )
                    {
                        ConsoleWirter.Error( ex.Message );
                    }
                    finally
                    {
                        Console.WriteLine( );
                    }
                }
            }, cancellationToken );


            _logger.Info( $"注册成功" );
            await Task.CompletedTask;
        }

        public async Task StopAsync( CancellationToken cancellationToken )
        {
            _logger.Info( $"注销成功" );
            await Task.CompletedTask;
        }
    }
}
